function type_id=h5typeput(h5file,type_path,type)
% H5TYPEPUT:  place a user defined datatype in an hdf5 file
%
%   TYPE_ID=H5TYPEPUT(H5FILE,TYPE_PATH,TYPE) creates the specified by
%   TYPE_PATH.  H5FILE can be a file name or a H5ML.id object type_path is
%   the hdf5 path relative to the H5ML.id object or the file itself  
%
%   TYPE can be an h5type object or it can be a matlab structure
%   representing the type.  Care must be exercised when using the structure
%   input as only the layout of the structure is used in creating the type
%   and it is not gauranteed that the data represented in the structure
%   will fit in the type when storing the data.  The structure that work
%   have all terminal leaves with the same the number of elements
%   consisting of atomic types if only a single argument is given the type
%   is generated from a structure but not stored to a file.
%
%   This function requires R2009b or higher.
%
%   Example:  Create a named datatype 'mytype' corresponding to double 
%   precision.
%       h5filecreate('myfile.h5');
%       h5groupput('myfile.h5','/g1');
%       dtype = H5T.copy('H5T_NATIVE_DOUBLE');
%       h5typeput('myfile.h5','/g1/mytype',dtype);
%       h5dump('myfile.h5');
%
%   Example:  Create a compound datatype using MATLAB structures.
%       h5filecreate('myfile.h5');
%       h5groupput('myfile.h5','/g1');
%       s.name = '';
%       s.rank = '';
%       s.value = [];
%       h5typeput('myfile.h5','/g1/mytype2',s);
%       h5dump('myfile.h5');
%
%   See also:  h5dataput, h5groupput.
%
%   Copyright 2010 The MathWorks, Inc.  
%   Full credit to Philip Top (LLNL).

v = version('-release');
switch(v)
    case {'2007a', '2007b', '2008a', '2008b','2009a'}
        error('HDF5TOOLS:H5LINKPUT:notAvailable', ...
            'H5TYPEPUT requires 2009b or higher to work.');
end

if (nargin>1)
    if ~ischar(h5file)
        if ~isequal(class(h5file),'H5ML.id')
            error('MATLAB:H5TYPEPUT:badDatatype', ...
                'Filename input argument must have datatype char.' );
            
        end
    end
    
    if ~ischar(type_path)
        error('MATLAB:H5TYPEPUT:badDatatype', ...
            'TYPE_PUT input argument must have datatype char.' );
    end
end

if ~isstruct(type)
    if (isa(type,'H5ML.id'))
        try
            sz=H5T.get_size(type);
        catch ME
            error('MATLAB:H5TYPEPUT:badDatatype', ...
                'TYPE not of the requisite types: must be a HDF5 type or a struct' );
        end
    else
        error('MATLAB:H5TYPEPUT:badDatatype', ...
            'TYPE not of the requisite types: must be a HDF5 type or a struct' );
    end
end
if (nargin>1)
    
    flags = 'H5F_ACC_RDWR';
    plist_id = 'H5P_DEFAULT';
    
    if ischar(h5file)
        file_id = H5F.open ( h5file, flags, plist_id );
    else
        file_id=h5file;
    end
    
    lcpl = H5P.create('H5P_LINK_CREATE');
    H5P.set_create_intermediate_group(lcpl,1);
    
    if (isa(type,'H5ML.id'))
        %this appears to be a bug in the matlab library preventing me from
        %using this 1.8.3 version of the function
        %H5T.commit(file_id,type_path,type,lcpl,'H5P_DEFAULT','H5P_DEFAULT');
        type_id=type;
        H5T.commit(file_id,type_path,type_id);
    else
        type_id=struct_to_h5type(type);
        if (isequal(type_id,-1))
            error('MATLAB:H5TYPEPUT:badDatatype', ...
                'Structure is invalid for formation of data type' );
        end
        
        %H5T.commit(file_id,type_path,type_id,lcpl,'H5P_DEFAULT','H5P_DEFAULT');
        H5T.commit(file_id,type_path,type_id);
    end
    
    if (nargout==0)
        H5T.close(type_id);
    end
    
    if ischar(h5file)
        H5F.close(file_id);
    end
    
else %operate for a single argument
    if (isstruct(type))
        type_id=struct_to_h5type(type);
    else
        type_id=H5T.copy(type);
    end
end


end
